package com.lry.basic.netty.websocket;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @author:刘仁有
 * @desc:
 * @email:953506233@qq.com
 * @data:2019/10/15
 */
public class WebSocketServer {
    public static void main(String[] args) {
        WebSocketServer ws = new WebSocketServer();
        ws.run();
    }
    public void run(){
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup worker = new NioEventLoopGroup();
        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss,worker);
            serverBootstrap.channel(NioServerSocketChannel.class);
            serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new HttpServerCodec());
                    // 对写大数据流的支持
                    pipeline.addLast(new ChunkedWriteHandler());
                    // 对httpMessage进行聚合，聚合成FullHttpRequest或FullHttpResponse
                    // 几乎在netty中的编程，都会使用到此hanler
                    pipeline.addLast(new HttpObjectAggregator(1024*64));

                    // ====================== 以上是用于支持http协议    ======================

                    // ====================== 以下是支持httpWebsocket ======================

                    /**
                     * websocket 服务器处理的协议，用于指定给客户端连接访问的路由 : /ws
                     * 本handler会帮你处理一些繁重的复杂的事
                     * 会帮你处理握手动作： handshaking（close, ping, pong） ping + pong = 心跳
                     * 对于websocket来讲，都是以frames进行传输的，不同的数据类型对应的frames也不同
                     */
                    pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

                    // 自定义的handler
                    pipeline.addLast(new ChatHandler());

                }
            });

            ChannelFuture future = serverBootstrap.bind(8088).sync();
            System.out.println("start.....");
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }
    }
}
